package cn.monkey.family.bean.container.spring;

import cn.monkey.family.data.utils.ClassUtil;
import cn.monkey.family.bean.container.BeanContainer;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.NonNull;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;

public abstract class AbstractSpringBeanContainer<T> implements BeanContainer<T>, ApplicationContextAware, InitializingBean {

    protected final Class<T> type;

    protected Map<String, T> beanMap;

    protected ApplicationContext applicationContext;

    public AbstractSpringBeanContainer() {
        this.type = ClassUtil.getActualType(this, AbstractSpringBeanContainer.class, "T");
        this.beanMap = Collections.emptyMap();
    }

    @Override
    public T getBean(String beanName) {
        return this.beanMap.get(beanName);
    }

    @Override
    public Collection<T> getAll() {
        return this.beanMap.values();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (this.applicationContext == null) {
            return;
        }
        this.beanMap = Collections.unmodifiableMap(this.applicationContext.getBeansOfType(this.type));
    }

    @Override
    public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
